今天主要利用 <canvas>
這個 HTML 元素來做出我們要的功能,我們可以利用程式腳本在這個元素上繪圖(通常是用 JS)、合成圖片或動畫效果。
而我們今天所要的功能為在畫布按下鼠標並拖曳可以畫出色彩,並會線條改變粗細,放開或離開畫布就停止。
首先,獲取canvas元素。
<canvas id="draw" width="800" height="800"></canvas>
let canvas = document.querySelector('#draw');
由於一開始canvas為空白,需先存取渲染環境,在上面繪圖,然後才會顯現影像
getContext():此方法可以取得渲染環境及其繪圖函數(function),參數有'2d',
'webgl'(3d)等等。此處用2d
let ctx = canvas.getContext('2d');
設置canvas下的樣式及狀態
// 設置畫畫狀態
let drawing = false;
// 用來判斷線條變粗變細
let direction = -1;
// 設置初始座標
let x = 0,y = 0;
// 線條寬度(預設為1)
let lineWidth = 50;
ctx.lineWidth = lineWidth;
// 端點樣式:有 'square'(方)、'round' (圓)、(預設為butt(切平))
ctx.lineCap = 'round';
// 交叉點樣式:有'bevel'(斜角)'roun'(圓)、(預設為butt(尖角))
ctx.lineJoin = 'round';
顏色屬性HSL Colors,此屬性可透過色相環上的角度來取得不同顏色
hsl(hue, saturation(飽和度), lightness(亮度));
CanvasRenderingContext2D.strokeStyle圖形邊線的顏色和樣式。 預設 #000 (黑色).
CanvasRenderingContext2D.fillStyle 圖形內部的顏色和樣式。預設 #000 (黑色).
// 設置顏色初始值(角度)
let colorDeg = 0;
ctx.strokeStyle = `hsl(${colorDeg},100%,50%)`;
最後我們加上滑鼠事件來進行處理
canvas.addEventListener('mousedown', (e) => {
drawing = true;
// 紀錄當前滑鼠點擊的位置
[x, y] = [e.offsetX, e.offsetY];
});
CanvasRenderingContext2D.beginPath()
:此方法可創建一個新的路徑(表示開始畫)。
CanvasRenderingContext2D.moveTo()
:將一個新路徑的起始點移動到(x,y)坐標(剛剛滑鼠點擊紀錄的位置)
CanvasRenderingContext2D.lineTo()
:使用直線連接路徑最後的點到x,y坐標(當前最後點的位置)。
CanvasRenderingContext2D.stroke()
:根據當前的畫線樣式,渲染出當前或已經存在的路徑的方法。
canvas.addEventListener('mousemove', (e) => {
if (!drawing) {
return
}
// console.log('draw');
// 開始畫
ctx.beginPath();
// 每當移動(+1度)就改變色環角度
colorDeg = colorDeg < 360 ? colorDeg + 1 : 0;
// 如果減到小於1或+到大於50,就切換方向(變粗或變細)
if (lineWidth < 1 || lineWidth > 50) {
direction *= -1;
}
// 每當移動就改變粗細
lineWidth += direction;
ctx.lineWidth = lineWidth;
ctx.strokeStyle = `hsl(${colorDeg},100%,50%)`;
// 新路徑的起始點
ctx.moveTo(x, y);
// 使用直線連接路徑(當前的點到起始點)
ctx.lineTo(e.offsetX, e.offsetY);
// 更新紀錄當前滑鼠點擊的位置
[x, y] = [e.offsetX, e.offsetY];
// 如果不加上storke,就只是連起來,但沒畫出來,一定要加上storke來渲染
ctx.stroke();
});
canvas.addEventListener('mouseup', () => {
drawing = false;
});
// 不使用mouseout,因為會連續觸發
canvas.addEventListener('mouseleave', () => {
drawing = false;
});
最後結果如下